"""
start north rotate clockwise

0 = in arrow pointing in
1 = out arrow pointing out
2 = in arrow pointing out
3 = out arrow pointing in
4 = out cross
5 = in cross
6 = out hexagon
7 = in hexagon

0, 1 go together
2, 3 go together
4, 5 go together
6, 7 go together


puzzle:

0   1  2   3

4   5  6   7

8   9  10 11

12  13 14 15

"""
import random


#VARIABLE DECLARATION
pieces = [
    [0,5,3,3],
    [1,0,7,4],
    [4,2,5,1],
    [3,5,7,3],
    [2,5,3,6],
    [6,7,5,4],
    [4,0,0,6],
    [6,7,0,1],
    [2,3,4,0],
    [4,6,7,2],
    [1,1,2,7],
    [1,3,7,0],
    [5,7,6,1],
    [6,7,0,6],
    [3,2,0,6],
    [6,5,7,3]
    ]


connections = []
solved = False

#FUNCTION DECLARATION
def rotate(x):
    #rotate
    for i in range(0,3):
        z = random.randint(0,3)
        count = 0
        while count < z:
            top = x[i][0]
            x[i].pop(0)
            x[i].append(top)
            count += 1
    return x

def flip(x):
    for i in range(0,3):
        z = random.randint(0,1)
        if z == 1:
            top = x[i][0]
            x[i][0] = x[i][2]
            x[i][2] = top
    return x

# this function shuffles the puzzle randomly
def rand_s(p):
    random.shuffle(p)
    p = rotate(p)
    p = flip(p)
    return p

# next there should be a function which checks to see if the value is valid
def is_solved(x):
    if not are_connected(x[0][1],x[1][3]):
        return False
    if not are_connected(x[1][1],x[2][3]):
        return False
    if not are_connected(x[2][1],x[3][3]):
        return False
    if not are_connected(x[0][2],x[4][0]):
        return False
    if not are_connected(x[1][2],x[5][0]):
        return False
    if not are_connected(x[2][2],x[6][0]):
        return False
    if not are_connected(x[3][2],x[7][0]):
        return False
    if not are_connected(x[4][1],x[5][3]):
        return False
    if not are_connected(x[5][1],x[6][3]):
        return False
    if not are_connected(x[6][1],x[7][3]):
        return False
    if not are_connected(x[4][2],x[8][0]):
        return False
    if not are_connected(x[5][2],x[9][0]):
        return False
    if not are_connected(x[6][2],x[10][0]):
        return False
    if not are_connected(x[7][2],x[11][0]):
        return False
    if not are_connected(x[8][1],x[9][3]):
        return False
    if not are_connected(x[9][1],x[10][3]):
        return False
    if not are_connected(x[10][1],x[11][3]):
        return False
    if not are_connected(x[8][2],x[12][0]):
        return False
    if not are_connected(x[9][2],x[13][0]):
        return False
    if not are_connected(x[10][2],x[14][0]):
        return False
    if not are_connected(x[11][2],x[15][0]):
        return False
    if not are_connected(x[12][1],x[13][3]):
        return False
    if not are_connected(x[13][1],x[14][3]):
        return False
    if not are_connected(x[14][1],x[15][3]):
        return False
    else:
        return True

def are_connected(x,y):
    if (x == 0 and y == 1 or x == 1 and y == 0 or x == 2 and y == 3 or x == 3 and y == 2 or x == 4 and y == 5 or x == 5 and y == 4 or x == 6 and y == 7 or x == 7 and y == 6):
        return True
    return False

    
#MAIN LOOP
count = 0
while not(solved):
    pieces = rand_s(pieces)
    #print("not solved.")
    count += 1
    if is_solved(pieces):
        solved = True
        print("solved.")
        print(str(pieces))
        print(count)
